/* Declarations from DAVE3 Code Generation */
//#include "Main.h"
//#include "Sim_Network_Manage.h"
#include "BSW_Include.h"
#include "String.h"
#include <stdio.h>

//#include <DAVE3.h>

time_t RTC_Seconds;
RTC001_TimeHandle calendar = { 0U };
/* Forward reference */
void threadA(void const *argument);
void threadB(void const *argument);
void thrNetManage(void const *argument);
void thrRB_CmdExtract(void const *argument);
void thrCcpM(void const *argument);

void Ini_main(void const *argument);
void tmrRealtimeUp(void const *argument);
void thrRxData(void);
void thrUSB_BSL(void const *argument);
void thrPcCommunication(void const *argument);
void thrUploadMonitorData(void const *argument);

/* Thread IDs */
osThreadId threadA_id;
osThreadId threadB_id;
osThreadId thrNetManage_id;
osThreadId thrRB_CmdExtract_id;
osThreadId thrCcpM_id;
osThreadId thrISO15031_id;
osThreadId tmrRealtimeUp_id;
osThreadId thrRxData_id;
osThreadId thrUSB_BSL_id;
osThreadId thrPcCommunication_id;
osThreadId thrUploadMonitorData_id;
osThreadId thrReUploadMonitorData_id;
/* Thread definitions */
osThreadDef(threadA, osPriorityNormal, 1, 0);
osThreadDef(threadB, osPriorityNormal, 1, 0);
osThreadDef(thrNetManage, osPriorityNormal, 1, 0);
osThreadDef(thrRB_CmdExtract, osPriorityNormal, 1, 0);
osThreadDef(thrCcpM, osPriorityNormal, 1, 0);
osThreadDef(tmrRealtimeUp, osPriorityNormal, 1, 0);
osThreadDef(thrRxData, osPriorityNormal, 1, 0);
osThreadDef(thrPcCommunication, osPriorityBelowNormal, 1, 0);

osTimerId UserTimerID;
osTimerDef(UserTimer, (void*)UserTimer_Task);

/* mutex */
osMutexDef(Generbuf_Mutex);
// Declare mutex
osMutexId (Generbuf_Mutex_id); // Mutex ID
osMutexDef(SimTx_Mutex);
// Declare mutex
osMutexId (SimTx_Mutex_id); // Mutex ID
osMutexDef(StmTx4Rec_Mutex);
// Declare mutex
osMutexId (StmTx4Rec_Mutex_id); // Mutex ID
osMutexDef(CAN0Tx_Mutex);
// Declare mutex
osMutexId (CAN0Tx_Mutex_id); // Mutex ID
osMutexDef(CAN1Tx_Mutex);
// Declare mutex
osMutexId (CAN1Tx_Mutex_id); // Mutex ID

osMutexDef(DSListSystemFault_Mutex);
// Declare mutex
osMutexId (DSListSystemFault_Mutex_id); // Mutex ID
osMutexDef(DSListNetworkFault_Mutex);
// Declare mutex
osMutexId (DSListNetworkFault_Mutex_id); // Mutex ID
#if 1
uint16_t testbuf[340];
#endif
//char gps_utl[100];
int gps_len = 0;

//#define DS_Debug

#ifdef DS_Debug
uint8_t TestDS_TestAllArea = 0;
uint8_t TestDS_EraseAllArea = 0;
uint8_t TestDS_CheckStartEnd = 0;
uint8_t TestDS_WritePageContinue = 0;
uint8_t TestDS_ReadPage = 0;
uint8_t TestDS_ReadPageIdx = 0x0;
uint8_t TestDS_WritePage = 0;
uint8_t TestDS_WritePageIdx = 0x0;
uint8_t TestDS_WriteData = 0xAA;
uint8_t TestDS_StartUpload = 0;
uint8_t TestDS_StopUpload = 0;
uint8_t TestDS_GetsizeofRec = 0;
#endif

void threadA(void const *argument) {
	while(1){
	/*uint32_t secid = 100, write_addr = 458752, erase_cnt = 0, start_addr =
			458752, i;
	osDelay(15);
	while (1) {

		while (write_addr\

				< (DS_StartSectorNumber + DS_NumberSector) * DS_SectorSize) {

			//erase;
			if (erase_cnt * 16 * 4096 + start_addr < (write_addr + 340)) {
				Flash_Erase_Block64(start_addr + erase_cnt * 16 * 4096);
				//verify
				memset(testbuf, 0, 340 * 2);
				FLASH_Read(testbuf, start_addr + erase_cnt * 16 * 4096, 340);
				for (i = 0; i < 340; i++) {
					if (testbuf[i] != 0xff) {
						break;

					}
				}
				erase_cnt++;

			}

			//write
			for (i = 0; i < 340; i++) {
				testbuf[i] = i%256;

			}
			Flash_WaitBusy();
			S25FL032P_WriteEnable();
			S25FL032P_Prog_Anylen(write_addr, testbuf, 340);
			//read

			Flash_WaitBusy();

			memset(testbuf, 0, 340 * 2); //
			FLASH_Read(testbuf, write_addr, 340);

			//verify
			for (i = 0; i < 340; i++) {
				if (testbuf[i] != i%256) {

					break;
				}
			}
			write_addr += 340;
			osDelay(3);
		}
		write_addr = 409600;*/
#ifdef DS_Debug
		if(TestDS_TestAllArea == 1)
		{
			DS_TestAllArea();
			TestDS_TestAllArea = 0;
		}
		else if(TestDS_EraseAllArea == 1)
		{
			DS_EraseAllArea();
			TestDS_EraseAllArea = 0;
		}
		else if(TestDS_CheckStartEnd==1)
		{
			DS_CheckStartEndOfDataStorageArea();
			TestDS_CheckStartEnd = 0;
		}
		else if(TestDS_ReadPage==1)
		{
			S25FL032P_RD_PAGE(TestDS_ReadPageIdx*DS_PageSize, (uint16_t*)&DS.TxBuf[0]);
			TestDS_ReadPage = 0;
		}
		else if(TestDS_WritePage==1)
		{
			for(int i=0;i<256;i++)
			DS.TxBuf[i]= 0x55;
			DS.TxBuf[0] = TestDS_WritePageIdx;
			DS_ProgramPage(TestDS_WritePageIdx*256,&DS.TxBuf[0]);
			TestDS_WritePage = 0;
		}

		else if(TestDS_WritePageContinue==1)
		{
			for(int i=0;i<256;i++)
			DS.TxBuf[i]=TestDS_WriteData;
			DS.TxBuf[0] = DS.WritePageIdx;
			DS_WritePage(&DS.TxBuf[0]);
		}
		else if(TestDS_GetsizeofRec==1)
		{
		}
		else if(TestDS_StartUpload==1)
		{
		}
		else if(TestDS_StopUpload ==1 )
		{
		}
#endif
		osDelay(10);
	}
}

void threadB(void const *argument) {
//	static int CNT = 0;
	while (1) {

		osDelay(10);
	}
}

void thrCcpM(void const *argument) // no os wait function
{
	while (1) {
		FlashLED_100msTask(40); //其他灯指示CAN状态，GPS状态等
		osDelay(5);
	};
}

void thrRxData(void) {
	while (1) {
		osDelay(100);
		osSignalWait(0x2, osWaitForever);
		GPSInfoAnalyze();
	}
}

void thrNetManage(void const *argument) {
	PC.EnableSim5320 = 1;
	InitQueue(&StmTx);
	InitQueue(&USBRx);
	InitQueue(&Sim5320Rx);
#ifndef DS_Debug
	Sim_Stm_Init(PowerReset);
	Sim_Stm_Run(PowerOn);
	while (1) {
		if (PC.EnableSim5320 == 1) {
			osSignalWait(0x2, osWaitForever);
			osDelay(10); //10ms 处理一次

			Sim_Stm_Run(sim_event);

		}
	}
#endif
}

void tmrRealtimeUp(void const *argument) {
	static ubyte CNT = 0;
	int8_t data;
	PC.EnableRealTimeUpload = 1;
	DS_CheckStartEndOfDataStorageArea();
	while (1) {
		UpdateTIU_Res_100msTask();
		if ((PC.OnUsing != NoConnection) && (CNT++ >= UploadPeriod / RecPeriod)
				&& (PC.EnableRealTimeUpload == 1)) {
			CNT = 0;
			Pack_GPRS();
		}

		Pack_GPRS4Rec();
		while (!IsEmpty(&StmTx4Rec)) // 每次调用将buf中的数据全部发送完成
		{
			data = Dequeue(&StmTx4Rec);
		}
		DS_BuffWrite(&data, 1);

		osDelay(RecPeriod);
	}
}

void thrPcCommunication(void const *argument) {
	while (1) {
		PC_Communication();
		RTC001_Time(&RTC_Seconds);
		osDelay(1);
	}
}

int main(void) {
	DAVE_Init();
	Protocol_CANInitial();
	USBD_VCOM_Init();
	GPS_Init();
	DS_Initial();
//	GB_ConfigMsg_Initial();
	Enable_CAN_INH0;
	Enable_CAN_INH1;
	UserTimerID = osTimerCreate(osTimer(UserTimer), osTimerPeriodic, NULL );
//	osTimerStart(UserTimerID, 1);		//Timer for 1ms
	SimTx_Mutex_id = osMutexCreate(osMutex(SimTx_Mutex));
	StmTx4Rec_Mutex_id = osMutexCreate(osMutex(StmTx4Rec_Mutex));
	Generbuf_Mutex_id = osMutexCreate(osMutex(Generbuf_Mutex));
	CAN0Tx_Mutex_id = osMutexCreate(osMutex(CAN0Tx_Mutex));
	CAN1Tx_Mutex_id = osMutexCreate(osMutex(CAN1Tx_Mutex));
	DSListSystemFault_Mutex_id = osMutexCreate(
			osMutex(DSListSystemFault_Mutex));
	DSListNetworkFault_Mutex_id = osMutexCreate(
			osMutex(DSListNetworkFault_Mutex));

	memset(&TIU_Res, 0, sizeof(ResponseStr));
	memset(&ConditionStatistics, 0, sizeof(StrStatistics));
	/* Create thread X */
	threadA_id = osThreadCreate(osThread(threadA), NULL );
	threadB_id = osThreadCreate(osThread(threadB), NULL );

	tmrRealtimeUp_id = osThreadCreate(osThread(tmrRealtimeUp), NULL );
#ifndef	GB_USBDEBUG
	thrNetManage_id = osThreadCreate(osThread(thrNetManage), NULL );
#endif
	thrRB_CmdExtract_id = osThreadCreate(osThread(thrRB_CmdExtract), NULL );
	thrCcpM_id = osThreadCreate(osThread(thrCcpM), NULL );
	thrRxData_id = osThreadCreate(osThread(thrRxData), NULL );
	thrPcCommunication_id = osThreadCreate(osThread(thrPcCommunication), NULL );
	osKernelStart();
	while (1) {
		osDelay(1000);
	}
}

